package com.ts.api.module.api.service.impl;

import com.gitee.apanlh.util.algorithm.digest.MD5;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.valid.Assert;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.api.ApiApplyQueryStatusEnum;
import com.ts.api.common.constant.api.ApiBizTypeEnum;
import com.ts.api.common.constant.api.ApiEnum;
import com.ts.api.common.constant.productflow.ProductApplyFlowStatusEnum;
import com.ts.api.exp.ApiMsgException;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.bo.ApiBizMatchBO;
import com.ts.api.module.api.entity.bo.ApiDataExchangeBO;
import com.ts.api.module.api.entity.bo.ApiFilterParamBO;
import com.ts.api.module.api.entity.bo.ApiParameterBO;
import com.ts.api.module.api.entity.bo.ApiPreRequiredBO;
import com.ts.api.module.api.entity.bo.ApiRequiredFlowBO;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.api.entity.vo.ReqApiParameterVO;
import com.ts.api.module.api.entity.vo.RespApiApplyQueryVO;
import com.ts.api.module.api.entity.vo.RespV2ApiApplyVO;
import com.ts.api.module.api.entity.vo.RespV2ApiDataExchangeVO;
import com.ts.api.module.api.service.ApiBizDataExchangeService;
import com.ts.api.module.api.service.ApiBizRequiredService;
import com.ts.api.module.api.service.ApiMsgV2Service;
import com.ts.api.module.api.service.ApiUserRegister;
import com.ts.api.module.product.entity.po.ProductApplyFlowPO;
import com.ts.api.module.product.entity.qo.ProductApplyFlowQO;
import com.ts.api.module.product.service.ProductApplyFlowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 *  API-对方接入我方-V1业务层
 *
 *  @author Pan
 */
@Service
public class ApiMsgV2ServiceImpl implements ApiMsgV2Service {

    @Autowired
    private ApiBizRequiredService apiBizRequiredService;
    @Autowired
    private ApiBizDataExchangeService apiBizDataExchangeService;
    @Autowired
    private ApiUserRegister apiUserRegister;
    @Autowired
    private ProductApplyFlowService productApplyFlowService;

    @Override
    public RespV2ApiDataExchangeVO dataExchange(ApiKeyPO apiKeyPO, ReqApiParameterVO reqApiParameterVO) throws Exception {
        //  1.撞库前置校验-创建正常计划类型匹配（机构、平台）
        ApiBizMatchBO normalPlan = ApiBizMatchBO.createNormalPlan(true);
        ApiPreRequiredBO apiPreRequiredBO = ApiPreRequiredBO.create(reqApiParameterVO, ApiBizTypeEnum.DATA_EXCHANGE, null, normalPlan);
        ApiParameterBO apiParameterBO = apiBizRequiredService.preRequiredParam(apiPreRequiredBO);

        //  2.撞库匹配
        ApiDataExchangeBO apiDataExchangeBO = apiBizDataExchangeService.dataExchange(apiParameterBO);

        //  3.返回撞库结果
        RespV2ApiDataExchangeVO respV2ApiDataExchangeVO = RespV2ApiDataExchangeVO.create(apiDataExchangeBO, apiKeyPO);
        return respV2ApiDataExchangeVO;
    }

    @Override
    public RespV2ApiApplyVO apply(ApiKeyPO apiKeyPO, ReqApiParameterVO reqApiParameterVO) {
        //  1.查询是否渠道存在该流程
        ApiUserRequest apiUserRequest = reqApiParameterVO.getApiUserRequest();
        String phone = apiUserRequest.getPhone();
        Assert.isNotEmptyThrows(phone, new ApiMsgException(ApiEnum.API_REQUIRED_PARAM_NULL.format("phone")));
        String phoneMd5 = MD5.create().digestToHex(phone);

        ApiRequiredFlowBO apiRequiredFlowBO = ApiRequiredFlowBO.createByApiClientId(phoneMd5, apiKeyPO.getApiClientId());
        ProductApplyFlowPO productApplyFlowPO = apiBizRequiredService.requiredSucDataExchangeFlow(apiRequiredFlowBO);
        Assert.isNotNullThrows(productApplyFlowPO, new ApiMsgException(ApiEnum.API_APPLY_FLOW_ERROR));

        //  2.进件-前置参数验证
        ApiFilterParamBO apiFilterParamBO = ApiFilterParamBO.create("applyId");
        ApiBizMatchBO normalPlanApply = ApiBizMatchBO.createNormalPlanApply();
        ApiPreRequiredBO apiPreRequiredBO = ApiPreRequiredBO.create(reqApiParameterVO, ApiBizTypeEnum.APPLY, apiFilterParamBO, normalPlanApply);
        ApiParameterBO apiParameterBO = apiBizRequiredService.preRequiredParam(apiPreRequiredBO);

        //  3.注册用户
        apiUserRegister.applyUserRegister(apiParameterBO, productApplyFlowPO);

        //  4.返回响应
        RespV2ApiApplyVO respV2ApiApplyVO = RespV2ApiApplyVO.create(phoneMd5);
        return respV2ApiApplyVO;
    }

    @Override
    public RespApiApplyQueryVO applyStatusQuery(ApiKeyPO apiKeyPO, ReqApiParameterVO reqApiParameterVO) {
        Map<String, String> formMap = reqApiParameterVO.getFormMap();

        String phoneMd5 = formMap.get("applyId");
        Assert.isNotEmptyThrows(phoneMd5, new ApiMsgException(ApiEnum.API_REQUIRED_PARAM_NULL.format("applyId")));

        //  默认返回进件等待状态
        RespApiApplyQueryVO respApplyQueryVO = RespApiApplyQueryVO.create(phoneMd5, ApiApplyQueryStatusEnum.AWAIT);

        //  查询进件状态
        ProductApplyFlowQO productApplyFlowQO = new ProductApplyFlowQO();
        productApplyFlowQO.setApiClientId(apiKeyPO.getApiClientId());
        productApplyFlowQO.setPhoneMd5(phoneMd5);
        productApplyFlowQO.setApiEnvType(apiKeyPO.getApiEnvType());
        List<ProductApplyFlowPO> listProductApplyFlowPO = productApplyFlowService.list(productApplyFlowQO);

        //  分组转换流程状态
        Map<Integer, List<ProductApplyFlowPO>> flowMap = CollUtils.groupBy(listProductApplyFlowPO, ProductApplyFlowPO::getStatus);

        //  是否存在授权节点
        if (ValidParam.isNotEmpty(flowMap.get(ProductApplyFlowStatusEnum.USER_ACCEPT.getType()))) {
            respApplyQueryVO = RespApiApplyQueryVO.create(phoneMd5, ApiApplyQueryStatusEnum.SUC);
        }
        //  存在进件失败
        if (ValidParam.isNotEmpty(flowMap.get(ProductApplyFlowStatusEnum.APPLY_ERROR.getType()))) {
            respApplyQueryVO = RespApiApplyQueryVO.create(phoneMd5, ApiApplyQueryStatusEnum.FAIL);
        }
        //  我方业务校验失败
        if (ValidParam.isNotEmpty(flowMap.get(ProductApplyFlowStatusEnum.APPLY_BIZ_ERROR.getType()))) {
            respApplyQueryVO = RespApiApplyQueryVO.create(phoneMd5, ApiApplyQueryStatusEnum.FAIL);
        }
        return respApplyQueryVO;
    }
}
